package bugfixer;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.spy;

import java.util.ArrayList;

import junit.framework.Assert;

import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;

import com.globant.bugfixer.Report;
import com.globant.bugfixer.TrafficProductReplace;

/**
 * Unit test to evaluate the log classes functionality.
 * Uses an in-memory Derby database.
 * <p>
 * Evaluates both: log.details and log.reports.
 * 
 * @author		gonzalo.zarza
 */

public class MemoryLogsTestProductReplace {
	
    private static ApplicationContext      context;
    private static DataSourceInitializer   dataSourceInitializer;
	private static TrafficProductReplace   reports;
	@Spy TrafficProductReplace spy=new TrafficProductReplace();
	/* ------------------------------------------------------------------------------------------ */
	
	@BeforeClass
	public static void setUp() {
		
	    DriverManagerDataSource    dataSource;
	    	    
		context               = new ClassPathXmlApplicationContext("Spring-Module_test_logs.xml");		
		dataSource            = (DriverManagerDataSource) context.getBean("dataSource");
		
		dataSourceInitializer = new DataSourceInitializer();		
		dataSourceInitializer.setDataSource(dataSource);
				
		reports = (TrafficProductReplace) context.getBean("reportTraffic");
		
	}
	/* ------------------------------------------------------------------------------------------ */
	/* ------------------------------------------------------------------------------------------ */
	
	/**
	 * Test the classes of testGenericProductRelease
	 */
	@Test
	public void testGenericProductRelease() {	
		System.out.println("----------------------------------------------");
		System.out.println("NEW TEST");
		System.out.println("----------------------------------------------");

		//--- Elements with product_id =6
//    	Report report6_1=new Report();
//        report6_1.setTime_id(20121205);
//    	report6_1.setChannel_id(4);
//    	report6_1.setLanguage_id(2);
//    	report6_1.setProduct_id(6);
//    	report6_1.setCountry_id(230); 
//    	report6_1.setTraffic(2);
//    	
//    	Report report6_2=new Report();
//        report6_2.setTime_id(20121205);
//    	report6_2.setChannel_id(4);
//    	report6_2.setLanguage_id(5);
//    	report6_2.setProduct_id(6);
//    	report6_2.setCountry_id(211); 
//    	report6_2.setTraffic(10);
//    	
//    	Report report6_3=new Report();
//        report6_3.setTime_id(20121205);
//    	report6_3.setChannel_id(4);
//    	report6_3.setLanguage_id(9);
//    	report6_3.setProduct_id(6);
//    	report6_3.setCountry_id(210); 
//    	report6_3.setTraffic(20);
//    	
//    	ArrayList<Report> collection_product_6=new ArrayList<Report>();
//    	collection_product_6.add(report6_1);
//    	collection_product_6.add(report6_2);
//    	collection_product_6.add(report6_3);
    	
//    	//--- Elements with product_id =7
//    	Report report7_1=new Report();
//        report7_1.setTime_id(20121205);
//    	report7_1.setChannel_id(4);
//    	report7_1.setLanguage_id(2);
//    	report7_1.setProduct_id(7);
//    	report7_1.setCountry_id(230); 
//    	report7_1.setTraffic(2);
//    	
//    	Report report7_2=new Report();
//        report7_2.setTime_id(20121205);
//    	report7_2.setChannel_id(4);
//    	report7_2.setLanguage_id(5);
//    	report7_2.setProduct_id(7);
//    	report7_2.setCountry_id(211); 
//    	report7_2.setTraffic(10);
//    	
//    	Report report7_3=new Report();
//        report7_3.setTime_id(20121205);
//    	report7_3.setChannel_id(4);
//    	report7_3.setLanguage_id(9);
//    	report7_3.setProduct_id(7);
//    	report7_3.setCountry_id(210); 
//    	report7_3.setTraffic(20);
//    	
    	Report reportToReplace_1=new Report();
        reportToReplace_1.setTime_id(20121205);
    	reportToReplace_1.setChannel_id(4);
    	reportToReplace_1.setLanguage_id(2);
    	reportToReplace_1.setProduct_id(7);
    	reportToReplace_1.setCountry_id(230); 
    	reportToReplace_1.setTraffic(12);
    	
    	Report reportToReplace_2=new Report();
        reportToReplace_2.setTime_id(20121205);
    	reportToReplace_2.setChannel_id(5);
    	reportToReplace_2.setLanguage_id(2);
    	reportToReplace_2.setProduct_id(7);
    	reportToReplace_2.setCountry_id(230); 
    	reportToReplace_2.setTraffic(21);
    	
    	ArrayList<Report> collection_product_7=new ArrayList<Report>();
    	collection_product_7.add(reportToReplace_1);
    	collection_product_7.add(reportToReplace_2);
//    	collection_product_7.add(report7_3);
//    	collection_product_7.add(report7_4);
    	
    	//--- Workflow
    	TrafficProductReplace spy=spy(this.reports);
//    	Mockito.doReturn(collection_product_6).when(spy).getElementsFromReport(6);
//    	Mockito.doReturn(collection_product_7).when(spy).getElementsFromReport(7);
    	spy.replaceProduct(6,7);
    	
    	Mockito.verify(spy).deleteReport(reportToReplace_1);
    	Mockito.doNothing().when(spy).deleteReport(reportToReplace_1);

//    	Mockito.verify(spy).updateReport(24, reportToReplace_1);
//    	Mockito.doNothing().when(spy).updateReport(24, reportToReplace_1);
//    	Mockito.verify(spy).updateReport(23, reportToReplace_2);

	}
	
	/* ------------------------------------------------------------------------------------------ */
	
	/**
	 * Test the classes of the com.globant.util.log.logs package.
	 */
	@Test
	public void testTrafficProductReport() {	
	   


	    try{       
	    	//20121205,4,2,6,230,2
	    	/*
	    	 *   `time_dim_id` int(8) unsigned NOT NULL DEFAULT '0',
  `channel_dim_id` int(10) unsigned NOT NULL DEFAULT '0',
  `language_dim_id` int(10) unsigned NOT NULL DEFAULT '0',
  `product_dim_id` int(10) unsigned NOT NULL DEFAULT '0',
  `country_dim_id` int(10) unsigned NOT NULL DEFAULT '0',
  `traffic` int(10) unsigned DEFAULT NULL,
	    	 */
	    	Report report=new Report();
	    	report.setTime_id(20121205);
	    	report.setChannel_id(4);
	    	report.setLanguage_id(2);
	    	report.setProduct_id(6);
	    	report.setCountry_id(230);    	

	    	
	        ArrayList<Report> reportList=new ArrayList<Report>();
	        
	        //Test getReport
	        reportList=reports.getReport(report);
	        
	        assertEquals(20121205, reportList.get(0).getTime_id());
	        assertEquals(4, reportList.get(0).getChannel_id());
	        assertEquals(2, reportList.get(0).getLanguage_id());
	        assertEquals(6, reportList.get(0).getProduct_id());
	      //  assertEquals(2, reportList.get(0).getTraffic());
	        
	        //Test updateReport
	        reports.updateReport(8, report);
	        
	        reportList=reports.getReport(report);
	        assertEquals(20121205, reportList.get(0).getTime_id());
	        assertEquals(4, reportList.get(0).getChannel_id());
	        assertEquals(2, reportList.get(0).getLanguage_id());
	        assertEquals(6, reportList.get(0).getProduct_id());
	        assertEquals(8, reportList.get(0).getTraffic());
	        
	        //Test insertReport  	
	    	
	        reports.insertReport(report, 570);
	        report.setProduct_id(570); //AFTER WE INSERT--BECAUSE IT IS A NEW PRODUCT
	        reportList=reports.getReport(report);
	        assertEquals(20121205, reportList.get(0).getTime_id());
	        assertEquals(4, reportList.get(0).getChannel_id());
	        assertEquals(2, reportList.get(0).getLanguage_id());
	        assertEquals(570, reportList.get(0).getProduct_id());
	        assertEquals(0, reportList.get(0).getTraffic());
	        
	        //Test getElementsFromReport
	        
	        ArrayList<Report> listReportsExpected=new ArrayList<Report>();
	        //(20121205,4,2,72,1,2),(20121205,4,2,72,230,1)
	    	Report report2=new Report();
	        report2.setTime_id(20121205);
	    	report2.setChannel_id(4);
	    	report2.setLanguage_id(2);
	    	report2.setProduct_id(72);
	    	report2.setCountry_id(1);    	
	    	report2.setTraffic(2);
	    	
	    	Report report3=new Report();
	        report3.setTime_id(20121205);
	    	report3.setChannel_id(4);
	    	report3.setLanguage_id(2);
	    	report3.setProduct_id(72);
	    	report3.setCountry_id(230); 
	    	report3.setTraffic(1);

	    	listReportsExpected.add(report2);
	    	listReportsExpected.add(report3);
	    	
	    	ArrayList<Report> reportAnswer=reports.getElementsFromReport(72);
	      //  System.out.println(listReportsExpected);
	      //  System.out.println(reportAnswer);
	    	assertEquals(listReportsExpected.toString(), reportAnswer.toString());
	    	
	        //Test isCombinationPresent
	    	//(20121205,4,2,6,230,2),(20121205,4,2,7,230,21)  --> The only difference is in the product
	    	Report report4=new Report();
	        report4.setTime_id(20121205);
	    	report4.setChannel_id(4);
	    	report4.setLanguage_id(2);
	    	report4.setProduct_id(6);
	    	report4.setCountry_id(230); 
	    	report4.setTraffic(2);

	    	int productToCheck=7;

	    	Report reportExpec=new Report();
	        reportExpec.setTime_id(20121205);
	    	reportExpec.setChannel_id(4);
	    	reportExpec.setLanguage_id(2);
	    	reportExpec.setProduct_id(productToCheck);
	    	reportExpec.setCountry_id(230); 
	    	reportExpec.setTraffic(12);
	    	
	    	assertEquals(reportExpec.toString(), reports.isCombinationPresent(report4, productToCheck).toString());
	    	
	    	productToCheck=11;
	    	
	    	Assert.assertNull(reports.isCombinationPresent(report4, productToCheck));
	        //Test deleteReports
	    	//(20121205,4,2,6,230,2)
	    	Report report6=new Report();
	        report6.setTime_id(20121205);
	    	report6.setChannel_id(4);
	    	report6.setLanguage_id(2);
	    	report6.setProduct_id(6);
	    	report6.setCountry_id(230); 
	    	report6.setTraffic(8);
	    	
		    ArrayList<Report> listReportsExpected6=new ArrayList<Report>();
		    listReportsExpected6.add(report6);
		    
		   // System.out.println(reports.getReport(report6).toString());
		   // System.out.println(listReportsExpected6.toString());
	    	assertEquals(listReportsExpected6.toString(),reports.getReport(report6).toString());
	    	reports.deleteReport(report6);
	    	
	    	listReportsExpected6.remove(0);
	    	assertEquals(listReportsExpected6.toString(),reports.getReport(report6).toString());
	    } catch (DataAccessException e){
	        e.printStackTrace();
	        fail("Operation failed!");
	    }          
	} 

	
}
